(*******************************************************************************
h264tables.pas
Copyright (c) 2010-2017 David Pethes

This file is part of Fev.

Fev is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Fev is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Fev.  If not, see <http://www.gnu.org/licenses/>.

*******************************************************************************)

unit h264tables;

{$mode objfpc}{$H+}

interface

type
vlc_bits_len = array[0..1] of byte;  //bit pattern, pattern length

(*******************************************************************************
CBP mapping:
Table 9-4 – Assignment of codeNum to values of coded_block_pattern for macroblock prediction modes
*)
{ coded_block_pattern Intra_4x4 -> codeNum
}
const
tab_cbp_intra_4x4_to_codenum: array[0..47] of byte = (
   3, 29, 30, 17, 31, 18, 37,  8, 32, 38, 19,  9, 20, 10, 11,  2, 16, 33, 34, 21,
  35, 22, 39,  4, 36, 40, 23,  5, 24,  6,  7,  1, 41, 42, 43, 25, 44, 26, 46, 12,
  45, 47, 27, 13, 28, 14, 15,  0
);

tab_cbp_inter_4x4_to_codenum : array[0..47] of byte = (
   0,  2,  3,  7,  4,  8, 17, 13,  5, 18,  9, 14, 10, 15, 16, 11,  1, 32, 33, 36,
  34, 37, 44, 40, 35, 45, 38, 41, 39, 42, 43, 19,  6, 24, 25, 20, 26, 21, 46, 28,
  27, 47, 22, 29, 23, 30, 31, 12
);


(*******************************************************************************
Table 8-13 – Specification of QPC as a function of qPI
0..29: qpc = qp
*)
tab_qp_chroma: array[30..51] of byte =
  (29,30,31,32,32,33,34,34,35,35,36,36,37,37,37,38,38,38,39,39,39,39);


(*******************************************************************************
coef_token mapping:
Table 9-5 – coeff_token mapping to TotalCoeff( coeff_token ) and TrailingOnes( coeff_token )

index: [tablenum, TotalCoeff 0..16, TrailingOnes 0..3]

tables 0..2 (jvt-d036):
4+4 bit code/length

last table is FLC, so we could generate the values in code (jvt-c028):
  N >= 8 : 6 bit FLC xxxxyy, as follows:
  NumCoeff–1 is transmitted in the first 4 bits (xxxx).  The last 2 bits (yy) are used for T1.  Since NumCoeff=0 also has to be represented, the codeword 000011 is used for this.
  For chroma DC, Num-VLC_Chroma_DC is used.

*)
const
tab_coef_num: array[0..3, 0..16, 0..3] of vlc_bits_len =
(
  (
    (                (%1, 1),                 (%0, 1),                 (%0, 1),                 (%0, 1)),
    (           (%000101, 6),                (%01, 2),                 (%0, 1),                 (%0, 1)),
    (         (%00000111, 8),            (%000100, 6),               (%001, 3),                 (%0, 1)),
    (        (%000000111, 9),          (%00000110, 8),           (%0000101, 7),             (%00011, 5)),
    (      (%0000000111, 10),         (%000000110, 9),          (%00000101, 8),            (%000011, 6)),
    (     (%00000000111, 11),       (%0000000110, 10),         (%000000101, 9),           (%0000100, 7)),
    (   (%0000000001111, 13),      (%00000000110, 11),       (%0000000101, 10),          (%00000100, 8)),
    (   (%0000000001011, 13),    (%0000000001110, 13),      (%00000000101, 11),         (%000000100, 9)),
    (   (%0000000001000, 13),    (%0000000001010, 13),    (%0000000001101, 13),       (%0000000100, 10)),
    (  (%00000000001111, 14),   (%00000000001110, 14),    (%0000000001001, 13),      (%00000000100, 11)),
    (  (%00000000001011, 14),   (%00000000001010, 14),   (%00000000001101, 14),    (%0000000001100, 13)),
    ( (%000000000001111, 15),  (%000000000001110, 15),   (%00000000001001, 14),   (%00000000001100, 14)),
    ( (%000000000001011, 15),  (%000000000001010, 15),  (%000000000001101, 15),   (%00000000001000, 14)),
    ((%0000000000001111, 16),  (%000000000000001, 15),  (%000000000001001, 15),  (%000000000001100, 15)),
    ((%0000000000001011, 16), (%0000000000001110, 16), (%0000000000001101, 16),  (%000000000001000, 15)),
    ((%0000000000000111, 16), (%0000000000001010, 16), (%0000000000001001, 16), (%0000000000001100, 16)),
    ((%0000000000000100, 16), (%0000000000000110, 16), (%0000000000000101, 16), (%0000000000001000, 16))
  ),
  (
    (               (%11, 2),                 (%0, 1),                 (%0, 1),                 (%0, 1)),
    (           (%001011, 6),                (%10, 2),                 (%0, 1),                 (%0, 1)),
    (           (%000111, 6),             (%00111, 5),               (%011, 3),                 (%0, 1)),
    (          (%0000111, 7),            (%001010, 6),            (%001001, 6),              (%0101, 4)),
    (         (%00000111, 8),            (%000110, 6),            (%000101, 6),              (%0100, 4)),
    (         (%00000100, 8),           (%0000110, 7),           (%0000101, 7),             (%00110, 5)),
    (        (%000000111, 9),          (%00000110, 8),          (%00000101, 8),            (%001000, 6)),
    (     (%00000001111, 11),         (%000000110, 9),         (%000000101, 9),            (%000100, 6)),
    (     (%00000001011, 11),      (%00000001110, 11),      (%00000001101, 11),           (%0000100, 7)),
    (    (%000000001111, 12),      (%00000001010, 11),      (%00000001001, 11),         (%000000100, 9)),
    (    (%000000001011, 12),     (%000000001110, 12),     (%000000001101, 12),      (%00000001100, 11)),
    (    (%000000001000, 12),     (%000000001010, 12),     (%000000001001, 12),      (%00000001000, 11)),
    (   (%0000000001111, 13),    (%0000000001110, 13),    (%0000000001101, 13),     (%000000001100, 12)),
    (   (%0000000001011, 13),    (%0000000001010, 13),    (%0000000001001, 13),    (%0000000001100, 13)),
    (   (%0000000000111, 13),   (%00000000001011, 14),    (%0000000000110, 13),    (%0000000001000, 13)),
    (  (%00000000001001, 14),   (%00000000001000, 14),   (%00000000001010, 14),    (%0000000000001, 13)),
    (  (%00000000000111, 14),   (%00000000000110, 14),   (%00000000000101, 14),   (%00000000000100, 14))
  ),
  (
    (             (%1111, 4),                 (%0, 1),                 (%0, 1),                 (%0, 1)),
    (           (%001111, 6),              (%1110, 4),                 (%0, 1),                 (%0, 1)),
    (           (%001011, 6),             (%01111, 5),              (%1101, 4),                 (%0, 1)),
    (           (%001000, 6),             (%01100, 5),             (%01110, 5),              (%1100, 4)),
    (          (%0001111, 7),             (%01010, 5),             (%01011, 5),              (%1011, 4)),
    (          (%0001011, 7),             (%01000, 5),             (%01001, 5),              (%1010, 4)),
    (          (%0001001, 7),            (%001110, 6),            (%001101, 6),              (%1001, 4)),
    (          (%0001000, 7),            (%001010, 6),            (%001001, 6),              (%1000, 4)),
    (         (%00001111, 8),           (%0001110, 7),           (%0001101, 7),             (%01101, 5)),
    (         (%00001011, 8),          (%00001110, 8),           (%0001010, 7),            (%001100, 6)),
    (        (%000001111, 9),          (%00001010, 8),          (%00001101, 8),           (%0001100, 7)),
    (        (%000001011, 9),         (%000001110, 9),          (%00001001, 8),          (%00001100, 8)),
    (        (%000001000, 9),         (%000001010, 9),         (%000001101, 9),          (%00001000, 8)),
    (      (%0000001101, 10),         (%000000111, 9),         (%000001001, 9),         (%000001100, 9)),
    (      (%0000001001, 10),       (%0000001100, 10),       (%0000001011, 10),       (%0000001010, 10)),
    (      (%0000000101, 10),       (%0000001000, 10),       (%0000000111, 10),       (%0000000110, 10)),
    (      (%0000000001, 10),       (%0000000100, 10),       (%0000000011, 10),       (%0000000010, 10))
  ),
  (
    (           (%000011, 6),                 (%0, 1),                 (%0, 1),                 (%0, 1)),
    (           (%000000, 6),            (%000001, 6),                 (%0, 1),                 (%0, 1)),
    (           (%000100, 6),            (%000101, 6),            (%000110, 6),                 (%0, 1)),
    (           (%001000, 6),            (%001001, 6),            (%001010, 6),            (%001011, 6)),
    (           (%001100, 6),            (%001101, 6),            (%001110, 6),            (%001111, 6)),
    (           (%010000, 6),            (%010001, 6),            (%010010, 6),            (%010011, 6)),
    (           (%010100, 6),            (%010101, 6),            (%010110, 6),            (%010111, 6)),
    (           (%011000, 6),            (%011001, 6),            (%011010, 6),            (%011011, 6)),
    (           (%011100, 6),            (%011101, 6),            (%011110, 6),            (%011111, 6)),
    (           (%100000, 6),            (%100001, 6),            (%100010, 6),            (%100011, 6)),
    (           (%100100, 6),            (%100101, 6),            (%100110, 6),            (%100111, 6)),
    (           (%101000, 6),            (%101001, 6),            (%101010, 6),            (%101011, 6)),
    (           (%101100, 6),            (%101101, 6),            (%101110, 6),            (%101111, 6)),
    (           (%110000, 6),            (%110001, 6),            (%110010, 6),            (%110011, 6)),
    (           (%110100, 6),            (%110101, 6),            (%110110, 6),            (%110111, 6)),
    (           (%111000, 6),            (%111001, 6),            (%111010, 6),            (%111011, 6)),
    (           (%111100, 6),            (%111101, 6),            (%111110, 6),            (%111111, 6))
  )
);

{
separate table for nC == -1 (chroma DC)
3+3 bit code/length
}
tab_coef_num_chroma_dc: array[0..4, 0..3] of vlc_bits_len =
(
  (    (%01, 2),        (%0, 1),        (%0, 1),       (%0, 1)),
  ((%000111, 6),        (%1, 1),        (%0, 1),       (%0, 1)),
  ((%000100, 6),   (%000110, 6),      (%001, 3),       (%0, 1)),
  ((%000011, 6),  (%0000011, 7),  (%0000010, 7),  (%000101, 6)),
  ((%000010, 6), (%00000011, 8), (%00000010, 8), (%0000000, 7))
);



(*******************************************************************************
total_zeros
*)
{ Table 9-7 – total_zeros tables for 4x4 blocks with TotalCoeff( coeff_token ) 1 to 7
  index: TotalCoeff( coeff_token ) 1..7, total_zeros 0..15
}
const
tab_total_zeros0: array[1..7, 0..15] of vlc_bits_len =
(
  ( (1, 1), (3, 3), (2, 3), (3, 4), (2, 4), (3, 5), (2, 5), (3, 6), (2, 6), (3, 7),
    (2, 7), (3, 8), (2, 8), (3, 9), (2, 9), (1, 9) ),
  ( (7, 3), (6, 3), (5, 3), (4, 3), (3, 3), (5, 4), (4, 4), (3, 4), (2, 4), (3, 5),
    (2, 5), (3, 6), (2, 6), (1, 6), (0, 6), (0, 0) ),
  ( (5, 4), (7, 3), (6, 3), (5, 3), (4, 4), (3, 4), (4, 3), (3, 3), (2, 4), (3, 5),
    (2, 5), (1, 6), (1, 5), (0, 6), (0, 0), (0, 0) ),
  ( (3, 5), (7, 3), (5, 4), (4, 4), (6, 3), (5, 3), (4, 3), (3, 4), (3, 3), (2, 4),
    (2, 5), (1, 5), (0, 5), (0, 0), (0, 0), (0, 0) ),
  ( (5, 4), (4, 4), (3, 4), (7, 3), (6, 3), (5, 3), (4, 3), (3, 3), (2, 4), (1, 5),
    (1, 4), (0, 5), (0, 0), (0, 0), (0, 0), (0, 0) ),
  ( (1, 6), (1, 5), (7, 3), (6, 3), (5, 3), (4, 3), (3, 3), (2, 3), (1, 4), (1, 3),
    (0, 6), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0) ),
  ( (1, 6), (1, 5), (5, 3), (4, 3), (3, 3), (3, 2), (2, 3), (1, 4), (1, 3), (0, 6),
    (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0) )
);

{ Table 9-8 – total_zeros tables for 4x4 blocks with TotalCoeff( coeff_token ) 8 to 15
  index: TotalCoeff( coeff_token ) 8..15, total_zeros 0..8
}
tab_total_zeros1: array[8..15, 0..8] of vlc_bits_len =
(
  ((1, 6), (1, 4), (1, 5), (3, 3), (3, 2), (2, 2), (2, 3), (1, 3), (0, 6)),
  ((1, 6), (0, 6), (1, 4), (3, 2), (2, 2), (1, 3), (1, 2), (1, 5), (0, 0)),
  ((1, 5), (0, 5), (1, 3), (3, 2), (2, 2), (1, 2), (1, 4), (0, 0), (0, 0)),
  ((0, 4), (1, 4), (1, 3), (2, 3), (1, 1), (3, 3), (0, 0), (0, 0), (0, 0)),
  ((0, 4), (1, 4), (1, 2), (1, 1), (1, 3), (0, 0), (0, 0), (0, 0), (0, 0)),
  ((0, 3), (1, 3), (1, 1), (1, 2), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)),
  ((0, 2), (1, 2), (1, 1), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)),
  ((0, 1), (1, 1), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0))
);


{ Table 9-9 – total_zeros tables for chroma DC 2x2 blocks
index: TotalCoeff( coeff_token ) 1..3, total_zeros 0..3
}
tab_total_zeros_chroma_dc: array[1..3, 0..3] of vlc_bits_len =
(
  ((1, 1), (1, 2), (1, 3), (0, 3)),
  ((1, 1), (1, 2), (0, 2), (0, 0)),
  ((1, 1), (0, 1), (0, 0), (0, 0))
);



(*******************************************************************************
Table 9-10 – Tables for run_before

vlc for run_before >= 7 a zeros_left > 6 is generated:
0001
00001
000001
0000001...
-> (run_before - 4) x 0  + 1

index: zeros_left 1..7, run_before 0..6
*)
tab_run_before: array[1..7, 0..6] of vlc_bits_len =
(
  ((1, 1), (0, 1), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)),
  ((1, 1), (1, 2), (0, 2), (0, 0), (0, 0), (0, 0), (0, 0)),
  ((3, 2), (2, 2), (1, 2), (0, 2), (0, 0), (0, 0), (0, 0)),
  ((3, 2), (2, 2), (1, 2), (1, 3), (0, 3), (0, 0), (0, 0)),
  ((3, 2), (2, 2), (3, 3), (2, 3), (1, 3), (0, 3), (0, 0)),
  ((3, 2), (0, 3), (1, 3), (3, 3), (2, 3), (5, 3), (4, 3)),
  ((7, 3), (6, 3), (5, 3), (4, 3), (3, 3), (2, 3), (1, 3))
);



implementation
end.

